package com.yanqu.road.server.manger;

import com.yanqu.road.entity.cmd.CmdStatisticsData;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CommandStatisticsMgr {
    private static Map<Integer, CmdStatisticsData> commandStatisticsDataMap = new ConcurrentHashMap<>();

    //记录一下玩家被异常踢下线次数
    private static Map<Long, Map<Integer, Integer>> secondCommandKickTimesMap = new ConcurrentHashMap<>();
    private static Logger cmdLogger = LogManager.getLogger("COMMAND_TIME");

    public static void addCommandData(int cmdCode, long executeTime) {
        CmdStatisticsData data = commandStatisticsDataMap.get(cmdCode);
        if (data == null) {
            synchronized (commandStatisticsDataMap) {
                data = commandStatisticsDataMap.get(cmdCode);
                if (data == null) {
                    data = new CmdStatisticsData(cmdCode);
                    commandStatisticsDataMap.put(cmdCode, data);
                }
            }
        }
        synchronized (data) {
            data.addTotalTimes(1);
            data.addTotalExecuteTime(executeTime/1000);
        }
    }

    public static void resetAndLog() {
        ArrayList<CmdStatisticsData> list = new ArrayList<>(commandStatisticsDataMap.values());
        list.sort(Comparator.comparingLong(CmdStatisticsData::getAvgTime));
        Collections.reverse(list);
        int num = 0;

        for (CmdStatisticsData data :list) {
            if (data.getTotalTimes() <= 0) {
                continue;
            }
            num++;
            if (num <= 10) {
                cmdLogger.info("{} exeTimes: {}, exeCostTime: {},avgTime: {}",data.getCode(),data.getTotalTimes(),data.getTotalExecuteTime(),data.getAvgTime());
            }
        }
        num = 0;
        list.sort(Comparator.comparingLong(CmdStatisticsData::getTotalTimes));
        Collections.reverse(list);
        int totalTimes = 0;
        int costTime = 0;
        for (CmdStatisticsData data :list) {
            if (data.getTotalTimes() <= 0) {
                continue;
            }
            num++;
            totalTimes += data.getTotalTimes();
            costTime += data.getTotalExecuteTime();
            if (num <= 10) {
                cmdLogger.info("{} exeTimes: {}, exeCostTime: {},avgTime: {}", data.getCode(), data.getTotalTimes(), data.getTotalExecuteTime(), data.getAvgTime());
            }
            data.setTotalExecuteTime(0);
            data.setTotalTimes(0);
        }
        cmdLogger.info("exeTotalTimes: {}, exeCostTime: {}", totalTimes, costTime / 1000);
    }

    public static void addSecondCommandKickData(long userId, int cmdCode) {
        Map<Integer, Integer> map = secondCommandKickTimesMap.get(userId);
        if (map == null) {
            map = new ConcurrentHashMap<>();
            secondCommandKickTimesMap.put(userId, map);
        }
        Integer times = map.get(cmdCode);
        if (times == null) {
            times = 0;
        }
        map.put(cmdCode, times + 1);

        int totalTimes = 0;
        for (Integer oldTimes : map.values()) {
            totalTimes += oldTimes;
        }

        cmdLogger.info("check second cmd kick userId: {}, cmdCode: {}, kickTimes: {}, totalTimes: {}", userId, cmdCode, times + 1, totalTimes);
    }
}
